package com.android.lovely.ext

import android.Manifest
import android.app.Activity
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Outline
import android.graphics.RenderEffect
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.provider.Settings
import android.view.View
import android.view.ViewOutlineProvider
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.core.content.ContextCompat
import coil.load
import coil.request.ImageRequest
import coil.size.Size
import coil.transform.Transformation
import com.android.lovely.R
import com.android.lovely.api.service.downloadService
import com.android.lovely.ui.activity.UpLoadActivity
import com.android.lovely.util.BitmapUtil
import com.kotlin.extensions.appContext
import com.yalantis.ucrop.UCrop
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okio.buffer
import okio.sink
import java.io.File

// 生成随机文件名
private fun generateRandomFileName(ext: String): String {
    val randomChars = (1..6).map { ('a'..'z').random() }.joinToString("")
    return "$randomChars${System.currentTimeMillis()}$ext"
}

// 加载图片并设置占位图
fun ImageView.loadWithPlaceholder(
    data: Any?,
    placeholderResId: Int = R.drawable.icon_item_holder,
    builder: (ImageRequest.Builder.() -> Unit)? = null
) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        setRenderEffect(null)
    }
    load(data) {
        crossfade(true)
        placeholder(placeholderResId)
        error(placeholderResId)
        builder?.invoke(this)
    }
}

// 加载模糊图片
fun ImageView.loadBlurredImage(
    data: Any?,
    blurRadius: Float = 25f,
    cornerRadius: Float = 0f,
    builder: (ImageRequest.Builder.() -> Unit)? = null
) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        if (cornerRadius > 0) {
            clipToOutline = true
            outlineProvider = object : ViewOutlineProvider() {
                override fun getOutline(view: View, outline: Outline) {
                    outline.setRoundRect(0, 0, view.width, view.height, blurRadius)
                }
            }
        }
        setRenderEffect(
            RenderEffect.createBlurEffect(
                blurRadius * 2,
                blurRadius * 2,
                android.graphics.Shader.TileMode.CLAMP
            )
        )
        load(data) {
            crossfade(true)
            builder?.invoke(this)
        }
        return
    }
    load(data) {
        crossfade(true)
        builder?.invoke(this)
        transformations(object : Transformation {
            override val cacheKey: String
                get() = "blur($blurRadius,$cornerRadius)"

            override suspend fun transform(input: Bitmap, size: Size): Bitmap {
                return withContext(Dispatchers.Default) {
                    BitmapUtil.blur(appContext, input, 25f, cornerRadius)
                } ?: input
            }
        })
    }
}

// 启动图片裁剪
fun Activity.startImageCrop(
    launcher: ActivityResultLauncher<Intent>,
    sourceUri: Uri,
    aspectX: Int = 1,
    aspectY: Int = 1,
    isCircleCrop: Boolean = false
) {
    val destinationFile = File(appContext.filesDir, "uc/${generateRandomFileName(".png")}")
    destinationFile.parentFile?.mkdirs()
    if (destinationFile.exists()) {
        destinationFile.delete()
    }
    destinationFile.createNewFile()

    val destinationUri = Uri.fromFile(destinationFile)
    val intent = Intent(this, UpLoadActivity::class.java)
    intent.putExtra(UCrop.EXTRA_INPUT_URI, sourceUri)
    intent.putExtra(UCrop.EXTRA_ASPECT_RATIO_X, aspectX)
    intent.putExtra(UCrop.EXTRA_ASPECT_RATIO_Y, aspectY)
    intent.putExtra(UCrop.EXTRA_OUTPUT_URI, destinationUri)
    intent.putExtra(UCrop.Options.EXTRA_CIRCLE_DIMMED_LAYER, isCircleCrop)
    // 添加随机干扰参数
    intent.putExtra("_r", (1000..9999).random())
    launcher.launch(intent)
}

// 下载文件
suspend fun String.downloadFile(outputFilePath: String): Boolean {
    return runCatching {
        withContext(Dispatchers.IO) {
            val responseBody = downloadService.downloadFile(this@downloadFile)
            val outputFile = File(outputFilePath)
            outputFile.parentFile?.mkdirs()
            if (outputFile.exists()) outputFile.delete()
            outputFile.createNewFile()
            outputFile.sink().buffer().use { sink ->
                sink.writeAll(responseBody.source())
            }
            true
        }
    }.getOrDefault(false)
}

// 下载图片并复制到公共存储
suspend fun Context.downloadAndSaveImage(url: String): Boolean {
    val outputFile = File(cacheDir, url.substringBefore("?").substringAfterLast("/"))
    val isSuccess = url.downloadFile(outputFile.absolutePath)
    if (isSuccess) {
        outputFile.copyToPublic()
    }
    return isSuccess
}

// 复制文件到公共存储
suspend fun File.copyToPublic() = withContext(Dispatchers.IO) {
    if (Build.VERSION.SDK_INT < 29) {
        if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(
                appContext, Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
        ) {
            return@withContext
        }
        val dirType = Environment.DIRECTORY_PICTURES
        val picDir = Environment.getExternalStoragePublicDirectory(dirType)
        val destFile = File(
            picDir,
            "u/${(100..999).random()}_${name}"
        )
        copyTo(destFile, true)
        if (destFile.exists()) {
            val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
            intent.data = Uri.parse("file://" + destFile.absolutePath)
            appContext.sendBroadcast(intent)
        }
        return@withContext
    } else {
        val contentValues = ContentValues()
        contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, name)
        contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/*")
        val contentUri: Uri =
            if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI
            } else {
                MediaStore.Images.Media.INTERNAL_CONTENT_URI
            }
        contentValues.put(
            MediaStore.MediaColumns.RELATIVE_PATH,
            "${Environment.DIRECTORY_PICTURES}/u_${(100..999).random()}"
        )
        contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1)
        runCatching {
            val uri: Uri = appContext.contentResolver.insert(contentUri, contentValues)
                ?: return@withContext
            appContext.contentResolver.openOutputStream(uri)?.use { outputStream ->
                inputStream().use { input ->
                    input.copyTo(outputStream, 8192)
                }
                contentValues.clear()
                contentValues.put(MediaStore.Video.Media.IS_PENDING, 0)
                appContext.contentResolver.update(uri, contentValues, null, null)
            }
        }
    }
}

fun Activity.setNotifyPermission() {
    try {
        val localIntent = Intent().apply {
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
                putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
            } else action = "android.settings.APP_NOTIFICATION_SETTINGS"
            putExtra("app_package", packageName)
            putExtra("app_uid", applicationInfo.uid)
        }
        startActivity(localIntent)
    } catch (e: Exception) {
        val fallbackIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            data = Uri.fromParts("package", packageName, null)
        }
        if (fallbackIntent.resolveActivity(packageManager) != null) {
            startActivity(fallbackIntent)
        }
    }
}
